package com.jjzhk.common.beanConfig;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;

import java.util.UUID;
import java.util.stream.Stream;

/**
 * PuddoBeanDefinitionParser
 *
 * @author : JJZHK
 * @date : 2016-08-15
 * @comments :
 **/
public class PuddoBeanDefinitionParser implements BeanDefinitionParser {
    private Class<?> beanClass;
    private Logger logger = LoggerFactory.getLogger(PuddoBeanDefinitionParser.class);

    public PuddoBeanDefinitionParser(Class<?> beanClass) {
        this.beanClass = beanClass;
    }

    @Override
    public BeanDefinition parse(Element element, ParserContext parserContext) {
        RootBeanDefinition beanDefinition = new RootBeanDefinition();
        beanDefinition.setBeanClass(beanClass);
        beanDefinition.setLazyInit(false);

        if (element.getLocalName().equals("application"))
        {
            String port = element.getAttribute("port");
            beanDefinition.getPropertyValues().add("port", port);

            String host = element.getAttribute("host");
            beanDefinition.getPropertyValues().add("host", host);
            String beanID = "puddo::application";

            long count = Stream.of(parserContext.getRegistry().getBeanDefinitionNames()).filter(s -> s.equals(beanID)).count();

            if (count <= 0)
            {
                parserContext.getRegistry().registerBeanDefinition(beanID, beanDefinition);
            }
            else
            {
                throw new IllegalStateException("Duplicate spring bean puddo:application");
            }
        }

        if (element.getLocalName().equals("registry"))
        {
            String address = element.getAttribute("address");
            beanDefinition.getPropertyValues().add("address", address);

            String port = element.getAttribute("port");
            beanDefinition.getPropertyValues().add("port", port);
            String beanID = "puddo::registry";

            long count = Stream.of(parserContext.getRegistry().getBeanDefinitionNames()).filter(s -> s.equals(beanID)).count();

            if (count <= 0)
            {
                parserContext.getRegistry().registerBeanDefinition(beanID, beanDefinition);
            }
            else
            {
                throw new IllegalStateException("Duplicate spring bean puddo:registry");
            }
        }

        if (element.getLocalName().equals("service"))
        {
            String packages = element.getAttribute("package");
            beanDefinition.getPropertyValues().add("annoPackage", packages);

            beanDefinition.getPropertyValues().add("SerializationClass", element.getAttribute("SerializationClass"));

            String beanID = "puddo::service";

            long count = Stream.of(parserContext.getRegistry().getBeanDefinitionNames()).filter(s -> s.equals(beanID)).count();

            if (count <= 0)
            {
                parserContext.getRegistry().registerBeanDefinition(beanID, beanDefinition);
            }
            else
            {
                throw new IllegalStateException("Duplicate spring bean puddo:service");
            }
        }

        if (element.getLocalName().equals("caller"))
        {
            String interfaces = element.getAttribute("interface");
            String ref = element.getAttribute("ref");

            beanDefinition.getPropertyValues().add("interfaces", interfaces);
            beanDefinition.getPropertyValues().add("ref", ref);
            beanDefinition.getPropertyValues().add("interval", element.getAttribute("interval"));
            beanDefinition.getPropertyValues().add("trycount", element.getAttribute("trycount"));
            beanDefinition.getPropertyValues().add("SerializationClass", element.getAttribute("SerializationClass"));
            parserContext.getRegistry().registerBeanDefinition(ref, beanDefinition);
        }

        return beanDefinition;
    }
}